<?php

/*
 * Table/PlanningSemaine.php
 */

namespace RHX\Model\Table;

use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\ResultSet\ResultSet;
use RHX\Model\Object\PlanningSemaine;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Sql;
use RHX\Helper\RHDateTime;
use RHX\Model\Object\Periode;
use RHX\Model\Object\Semaine;

class PlanningSemaineTable extends AbstractTableGateway {

    protected $table = 'rh_planning_semaine';

    public function __construct(Adapter $adapter) {
	$this->adapter			 = $adapter;
	$this->resultSetPrototype	 = new ResultSet();
	$this->resultSetPrototype->setArrayObjectPrototype(new PlanningSemaine($adapter));
	$this->initialize();
    }

    public function getAll() {
	return $this->select();
    }

    /**
     * Récupérer un Planning Semaine
     * 
     * @param type $id
     * @return PlanningSemaine
     * @throws \Exception
     */
    public function get($id) {
	$row = $this->select(array('id' => $id))
		->current();
	if (!$row)
	    throw new \Exception("Impossible de trouver #$id");

	return $row;
    }

    public function getPlannings(Array $array) {
	return $this->select(function(Select $select)use($array) {
			    $where = new Where();
			    $where->in('id', $array);
			    $select->where($where);
			});
    }

    public function erase($id) {
	return $this->delete(array('id' => $id));
    }

    public function save(PlanningSemaine $pl) {
	$data	 = array(
	    'matricule'		 => $pl->matricule,
	    'lundi'			 => $pl->lundi,
	    'lundi_code'		 => $pl->lundi_code,
	    'lundi_entree'		 => $pl->lundi_entree,
	    'lundi_sortie'		 => $pl->lundi_sortie,
	    'lundi_pause'		 => $pl->lundi_pause,
	    'lundi_repas'		 => $pl->lundi_repas,
	    'lundi_entree_ref'	 => $pl->lundi_entree_ref,
	    'lundi_sortie_ref'	 => $pl->lundi_sortie_ref,
	    'mardi'			 => $pl->mardi,
	    'mardi_code'		 => $pl->mardi_code,
	    'mardi_entree'		 => $pl->mardi_entree,
	    'mardi_sortie'		 => $pl->mardi_sortie,
	    'mardi_pause'		 => $pl->mardi_pause,
	    'mardi_repas'		 => $pl->mardi_repas,
	    'mardi_entree_ref'	 => $pl->mardi_entree_ref,
	    'mardi_sortie_ref'	 => $pl->mardi_sortie_ref,
	    'mercredi'		 => $pl->mercredi,
	    'mercredi_code'		 => $pl->mercredi_code,
	    'mercredi_entree'	 => $pl->mercredi_entree,
	    'mercredi_sortie'	 => $pl->mercredi_sortie,
	    'mercredi_pause'	 => $pl->mercredi_pause,
	    'mercredi_repas'	 => $pl->mercredi_repas,
	    'mercredi_entree_ref'	 => $pl->mercredi_entree_ref,
	    'mercredi_sortie_ref'	 => $pl->mercredi_sortie_ref,
	    'jeudi'			 => $pl->jeudi,
	    'jeudi_code'		 => $pl->jeudi_code,
	    'jeudi_entree'		 => $pl->jeudi_entree,
	    'jeudi_sortie'		 => $pl->jeudi_sortie,
	    'jeudi_pause'		 => $pl->jeudi_pause,
	    'jeudi_repas'		 => $pl->jeudi_repas,
	    'jeudi_entree_ref'	 => $pl->jeudi_entree_ref,
	    'jeudi_sortie_ref'	 => $pl->jeudi_sortie_ref,
	    'vendredi'		 => $pl->vendredi,
	    'vendredi_code'		 => $pl->vendredi_code,
	    'vendredi_entree'	 => $pl->vendredi_entree,
	    'vendredi_sortie'	 => $pl->vendredi_sortie,
	    'vendredi_pause'	 => $pl->vendredi_pause,
	    'vendredi_repas'	 => $pl->vendredi_repas,
	    'vendredi_entree_ref'	 => $pl->vendredi_entree_ref,
	    'vendredi_sortie_ref'	 => $pl->vendredi_sortie_ref,
	    'samedi'		 => $pl->samedi,
	    'samedi_code'		 => $pl->samedi_code,
	    'samedi_entree'		 => $pl->samedi_entree,
	    'samedi_sortie'		 => $pl->samedi_sortie,
	    'samedi_pause'		 => $pl->samedi_pause,
	    'samedi_repas'		 => $pl->samedi_repas,
	    'samedi_entree_ref'	 => $pl->samedi_entree_ref,
	    'samedi_sortie_ref'	 => $pl->samedi_sortie_ref,
	    'dimanche'		 => $pl->dimanche,
	    'dimanche_code'		 => $pl->dimanche_code,
	    'dimanche_entree'	 => $pl->dimanche_entree,
	    'dimanche_sortie'	 => $pl->dimanche_sortie,
	    'dimanche_pause'	 => $pl->dimanche_pause,
	    'dimanche_repas'	 => $pl->dimanche_repas,
	    'dimanche_entree_ref'	 => $pl->dimanche_entree_ref,
	    'dimanche_sortie_ref'	 => $pl->dimanche_sortie_ref,
	    'heure_travaille'	 => $pl->heure_travaille,
	    'retard'		 => $pl->retard,
	    'retard_heure'		 => $pl->retard_heure,
	    'heure_non_plannifie'	 => $pl->heure_non_planifie,
	    'coef'			 => $pl->coef,
	    'hebdo'			 => $pl->hebdo,
	    'taux'			 => $pl->taux,
	    'heure_prevues'		 => $pl->heure_prevues,
	    'heure_travail'		 => $pl->heure_travail,
	);
	$id	 = (int) $pl->id;
	if ($id == 0) {
	    $this->insert($data);

	    return $this->lastInsertValue;
	}
	elseif ($this->get($id)) {
	    $this->update($data, array('id' => $id));

	    return $id;
	}
	else {
	    throw new \Exception("Impossible de sélectionner #$id");
	}
    }

    /**
     * Planning Semaine d'un employé
     * 
     * @param int $matricule
     * @param string $lundi
     * @return PlanningSemaine
     */
    public function getByEmploye($matricule, $lundi) {
	return $this->select(function(Select $select)use($matricule, $lundi) {
			    $where = new Where();
			    $where->equalTo('lundi', $lundi);
			    $where->equalTo('matricule', $matricule);
			    $select->where($where);
			})->current();
    }

    /**
     * Planning des employés
     *
     * @param string $lundi
     * @param array $employeList
     * @param boolean $groupby
     * @return ResultSet
     */
    public function getPlanningByEmploye($lundi, Array $employeList, $groupby = false) {
	return $this->select(function(Select $select)use($lundi, $employeList, $groupby) {
			    $where = new Where();
			    $where->equalTo('lundi', $lundi);
			    if (count($employeList) != 0) {
				// Tableau non-Vide
				$where->in('matricule', $employeList);
			    }
			    $select->where($where);
			    if ($groupby) {
				$select->group('matricule');
			    }
			});
    }
    
    public function getByEmployeBeforeDay($matricule, $day){
        return $this->select(function(Select $select)use($matricule, $day) {
                            $firstFebruary = '13-02-01';
                            
			    $where = new Where();
			    $where->greaterThanOrEqualTo('lundi', $firstFebruary); // to reverify
                            $where->lessThanOrEqualTo('lundi', $day);
			    $where->equalTo('matricule', $matricule);
			    
			    $select->where($where);			    
			});
    }

    /**
     * Récupérer un planning à partir d'un jour de la semaine
     * 
     * @param string $day
     * @param int $matricule
     * @return \RHX\Model\Object\PlanningSemaine
     */
    public function getPlanningByDay($day, $matricule) {
	$sql = "SELECT rh_planning_semaine.* FROM rh_planning_semaine WHERE matricule = $matricule AND (lundi = '$day' OR mardi = '$day' OR mercredi = '$day' OR jeudi = '$day' OR vendredi = '$day' OR samedi = '$day' OR dimanche = '$day')";
	$result = $this->getAdapter()
		->query($sql)
		->execute();
	$current = $result->current();
	$planning = new PlanningSemaine($this->getAdapter(), $current);
	return $planning;
    }

    public function getVariable($periode, $site) {
	// Objet Sql
	$sql	 = new Sql($this->adapter);
	$select	 = $sql->select();
	$select->from(array('pls' => $this->table));
	$select->columns(array(
	    'heure_travaille',
	    'heure_non_plannifie',
	));

	// Semaine
	$select->join(array(
	    's' => 'rh_semaine',
		), 'pls.lundi = s.lundi', array(
	    'lundi'		 => 'lundi',
	    'dimanche'	 => 'dimanche',
	));

	// Periode_Semaine
	$select->join(array(
	    'ps' => 'rh_periode_semaine',
		), 'ps.semaine_id = s.id', array(
	    'ps_id' => 'id',
	));

	// Periode
	$select->join(array(
	    'p' => 'rh_periode',
		), 'ps.periode_id = p.id', array(
	    'periode_id'		 => 'id',
	    'periode_libelle'	 => 'libelle',
	));

	// Employé
	$select->join(array(
	    'e' => 'rh_employe',
		), 'pls.matricule = e.matricule', array(
	    'nom'		 => 'nom1',
	    'prenom'	 => 'prenom',
	    'contrat_debut'	 => 'contrat_debut',
	    'contrat_fin'	 => 'contrat_fin',
	));

	// Avenant
	$select->join(array(
	    'a' => 'rh_avenant',
		), 'e.avenant_id = a.id', array(
	    'avenant_debut'	 => 'debut',
	    'avenant_fin'	 => 'fin',
	));

	// Poste
	$select->join(array(
	    'po' => 'rh_poste',
		), 'a.poste_id = p.id', array(
	    'poste_libelle' => 'libelle',
	));

	// Condition
//	$where = new Where();
//	$where->equalTo('e.site_id', $site);
//	$where->equalTo('p.id', $periode);
//
//	$select->where($where);

	$state	 = $sql->prepareStatementForSqlObject($select);
	$result	 = $state->execute();

	return $result;
    }

    public function getVariables($periode, $site) {
	$sql	 = "SELECT e.matricule, e.nom1, e.prenom, e.contrat_debut, e.contrat_fin, po.libelle, po.code,
	    s.libelle AS 'semaine_libelle', s.lundi, s.dimanche, p.libelle AS 'periode_libelle',
	    pls.heure_travaille, pls.heure_non_plannifie, pls.retard, pls.retard_heure,
	    a.hebdo, a.taux
	    FROM rh_planning_semaine pls, rh_periode_semaine ps, rh_periode p, rh_semaine s, rh_avenant a, rh_poste po, rh_employe e
	    WHERE pls.matricule = e.matricule
	    AND e.avenant_id = a.id
	    AND a.poste_id = po.id
	    AND pls.lundi = s.lundi
	    AND ps.semaine_id = s.id
	    AND ps.periode_id = p.id
	    AND e.site_id = $site
	    AND p.id = $periode
		ORDER BY e.matricule ASC, s.id ASC";
	$result	 = $this->adapter
		->query($sql)
		->execute();
	// Parcours du résultat
	$rows	 = array();
	foreach ($result as $row) {
	    $rows[] = $row;
	}

	return $rows;
    }

    public function getVariablesByMatricule($periode, $site, $matricule) {
	$sql	 = "SELECT e.matricule, e.nom1, e.prenom, e.contrat_debut, e.contrat_fin, po.libelle, po.code,
	    s.libelle AS 'semaine_libelle', s.lundi, s.dimanche, p.libelle AS 'periode_libelle',
	    pls.heure_travaille, pls.heure_non_plannifie, a.hebdo, a.taux
	    FROM rh_planning_semaine pls, rh_periode_semaine ps, rh_periode p, rh_semaine s, rh_avenant a, rh_poste po, rh_employe e
	    WHERE pls.matricule = e.matricule
	    AND e.avenant_id = a.id
	    AND a.poste_id = po.id
	    AND pls.lundi = s.lundi
	    AND ps.semaine_id = s.id
	    AND ps.periode_id = p.id
	    AND e.site_id = $site
	    AND p.id = $periode
		AND e.matricule = $matricule
		ORDER BY e.matricule ASC, s.id ASC";
	$result	 = $this->adapter
		->query($sql)
		->execute();
	// Parcours du résultat
	$rows	 = array();
	foreach ($result as $row) {
	    $rows[] = $row;
	}

	return $rows;
    }

    public function fire($matricule) {
	// Date du jour
	$now		 = new RHDateTime();
//	// Lundi Prochain
//	$lundiNext	 = new RHDateTime();
//	$lundiNext->modify('next monday');
	// Dimanche Prochain
	$sundayNext	 = new RHDateTime();
	$sundayNext->modify('next sunday');

	$weekId = -1;

	// Mise à jour des plannings de la semaine en cours
	$currentWeek = $this->select(function(Select $select)use($matricule, $now, $sundayNext) {
			    $where = new Where();
			    $where->equalTo('matricule', $matricule);
			    $where->between('dimanche', $now->date(), $sundayNext->date());

			    $select->where($where);
			})->current();
	if ($currentWeek) {
	    // Teste
	    $lundi		 = new RHDateTime($currentWeek->lundi);
	    $mardi		 = new RHDateTime($currentWeek->mardi);
	    $mercredi	 = new RHDateTime($currentWeek->mercredi);
	    $jeudi		 = new RHDateTime($currentWeek->jeudi);
	    $vendredi	 = new RHDateTime($currentWeek->vendredi);
	    $samedi		 = new RHDateTime($currentWeek->samedi);
	    $dimanche	 = new RHDateTime($currentWeek->dimanche);
	    // Lundi
	    if ($lundi->isGT($now)) {
		$currentWeek->lundi_code	 = 0;
		$currentWeek->lundi_entree	 = '00:00';
		$currentWeek->lundi_sortie	 = '00:00';
		$currentWeek->lundi_pause	 = 0;
		$currentWeek->lundi_repas	 = 0;
	    }
	    // Mardi
	    if ($mardi->isGT($now)) {
		$currentWeek->mardi_code	 = 0;
		$currentWeek->mardi_entree	 = '00:00';
		$currentWeek->mardi_sortie	 = '00:00';
		$currentWeek->mardi_pause	 = 0;
		$currentWeek->mardi_repas	 = 0;
	    }
	    // Mercredi
	    if ($mercredi->isGT($now)) {
		$currentWeek->mercredi_code	 = 0;
		$currentWeek->mercredi_entree	 = '00:00';
		$currentWeek->mercredi_sortie	 = '00:00';
		$currentWeek->mercredi_pause	 = 0;
		$currentWeek->mercredi_repas	 = 0;
	    }
	    // Jeudi
	    if ($jeudi->isGT($now)) {
		$currentWeek->jeudi_code	 = 0;
		$currentWeek->jeudi_entree	 = '00:00';
		$currentWeek->jeudi_sortie	 = '00:00';
		$currentWeek->jeudi_pause	 = 0;
		$currentWeek->jeudi_repas	 = 0;
	    }
	    // Vendredi
	    if ($vendredi->isGT($now)) {
		$currentWeek->vendredi_code	 = 0;
		$currentWeek->vendredi_entree	 = '00:00';
		$currentWeek->vendredi_sortie	 = '00:00';
		$currentWeek->vendredi_pause	 = 0;
		$currentWeek->vendredi_repas	 = 0;
	    }
	    // Samedi
	    if ($samedi->isGT($now)) {
		$currentWeek->samedi_code	 = 0;
		$currentWeek->samedi_entree	 = '00:00';
		$currentWeek->samedi_sortie	 = '00:00';
		$currentWeek->samedi_pause	 = 0;
		$currentWeek->samedi_repas	 = 0;
	    }
	    // Dimanche
	    if ($dimanche->isGT($now) || $dimanche->isEqual($now)) {
		$currentWeek->dimanche_code	 = 0;
		$currentWeek->dimanche_entree	 = '00:00';
		$currentWeek->dimanche_sortie	 = '00:00';
		$currentWeek->dimanche_pause	 = 0;
		$currentWeek->dimanche_repas	 = 0;
	    }
	    $weekId = $currentWeek->id;
	}

	// On efface les semaines qui suivent
	$nextWeeks = $this->select(function (Select $select) use($matricule, $sundayNext) {
		    $where = new Where();
		    $where->equalTo('matricule', $matricule);
		    $where->greaterThan('dimanche', $sundayNext->date());
		    $select->where($where);
		});
	foreach ($nextWeeks as $w) {
	    $this->delete(array('id' => $w->id));
	}

	return array(
	    'currentWeek'	 => $weekId,
	    'nextWeekCount'	 => $nextWeeks->count(),
	);
    }

    public function hire($matricule, $template) {
	// Recherche de planning Semaine avec le template
	// Vue
	$psView		 = new \RHX\Model\View\PSPlanningView($this->adapter);
	// table
	$employeTable	 = new EmployeTable($this->adapter);

	// Employé
	$employe = $employeTable->get($matricule);
	$dispo	 = $employe->getDisponibilite();

	$rows	 = $psView->getByTemplate($template);
	// parcours
	$idArray = array();
	foreach ($rows as $row) {
	    $periode = $row->getPeriode();
	    $debut	 = new RHDateTime($periode->debut);
	    $fin	 = new RHDateTime($periode->fin);
	    $now	 = new RHDateTime();
	    $semaine = $row->getSemaine();
	    // On doit rechercher des plannings semaines dont les dates sont en cours ou avenir
	    if ($now->isBetween($debut, $fin)) {
		// La date du jour est entre le début et la fin de la période
		// On Crée un planning Semaine pour l'employé
		$planningSemaine		 = new PlanningSemaine($this->adapter);
		$planningSemaine->matricule	 = $matricule;

		// lundi
		$planningSemaine->lundi	 = $semaine->lundi;
		$lundi			 = new RHDateTime($semaine->lundi);
		if ($lundi->isGT($now)) {
		    // On utilise les disponibilité
		    $planningSemaine->lundi_code	 = $dispo->lundi;
		    $planningSemaine->lundi_entree	 = $dispo->lundi_entree;
		    $planningSemaine->lundi_sortie	 = $dispo->lundi_sortie;
		    $planningSemaine->lundi_pause	 = 0;
		    $planningSemaine->lundi_repas	 = 0;
		}
		else {
		    $planningSemaine->lundi_code	 = 3;
		    $planningSemaine->lundi_entree	 = '00:00';
		    $planningSemaine->lundi_sortie	 = '00:00';
		    $planningSemaine->lundi_pause	 = 0;
		    $planningSemaine->lundi_repas	 = 0;
		}

		// mardi
		$planningSemaine->mardi	 = $semaine->mardi;
		$mardi			 = new RHDateTime($semaine->mardi);
		if ($mardi->isGT($now)) {
		    // On utilise les disponibilité
		    $planningSemaine->mardi_code	 = $dispo->mardi;
		    $planningSemaine->mardi_entree	 = $dispo->mardi_entree;
		    $planningSemaine->mardi_sortie	 = $dispo->mardi_sortie;
		    $planningSemaine->mardi_pause	 = 0;
		    $planningSemaine->mardi_repas	 = 0;
		}
		else {
		    $planningSemaine->mardi_code	 = 3;
		    $planningSemaine->mardi_entree	 = '00:00';
		    $planningSemaine->mardi_sortie	 = '00:00';
		    $planningSemaine->mardi_pause	 = 0;
		    $planningSemaine->mardi_repas	 = 0;
		}

		// mercredi
		$planningSemaine->mercredi	 = $semaine->mercredi;
		$mercredi			 = new RHDateTime($semaine->mercredi);
		if ($mercredi->isGT($now)) {
		    // On utilise les disponibilité
		    $planningSemaine->mercredi_code		 = $dispo->mercredi;
		    $planningSemaine->mercredi_entree	 = $dispo->mercredi_entree;
		    $planningSemaine->mercredi_sortie	 = $dispo->mercredi_sortie;
		    $planningSemaine->mercredi_pause	 = 0;
		    $planningSemaine->mercredi_repas	 = 0;
		}
		else {
		    $planningSemaine->mercredi_code		 = 3;
		    $planningSemaine->mercredi_entree	 = '00:00';
		    $planningSemaine->mercredi_sortie	 = '00:00';
		    $planningSemaine->mercredi_pause	 = 0;
		    $planningSemaine->mercredi_repas	 = 0;
		}

		// jeudi
		$planningSemaine->jeudi	 = $semaine->jeudi;
		$jeudi			 = new RHDateTime($semaine->jeudi);
		if ($jeudi->isGT($now)) {
		    // On utilise les disponibilité
		    $planningSemaine->jeudi_code	 = $dispo->jeudi;
		    $planningSemaine->jeudi_entree	 = $dispo->jeudi_entree;
		    $planningSemaine->jeudi_sortie	 = $dispo->jeudi_sortie;
		    $planningSemaine->jeudi_pause	 = 0;
		    $planningSemaine->jeudi_repas	 = 0;
		}
		else {
		    $planningSemaine->jeudi_code	 = 3;
		    $planningSemaine->jeudi_entree	 = '00:00';
		    $planningSemaine->jeudi_sortie	 = '00:00';
		    $planningSemaine->jeudi_pause	 = 0;
		    $planningSemaine->jeudi_repas	 = 0;
		}

		// vendredi
		$planningSemaine->vendredi	 = $semaine->vendredi;
		$vendredi			 = new RHDateTime($semaine->vendredi);
		if ($vendredi->isGT($now)) {
		    // On utilise les disponibilité
		    $planningSemaine->vendredi_code		 = $dispo->vendredi;
		    $planningSemaine->vendredi_entree	 = $dispo->vendredi_entree;
		    $planningSemaine->vendredi_sortie	 = $dispo->vendredi_sortie;
		    $planningSemaine->vendredi_pause	 = 0;
		    $planningSemaine->vendredi_repas	 = 0;
		}
		else {
		    $planningSemaine->vendredi_code		 = 3;
		    $planningSemaine->vendredi_entree	 = '00:00';
		    $planningSemaine->vendredi_sortie	 = '00:00';
		    $planningSemaine->vendredi_pause	 = 0;
		    $planningSemaine->vendredi_repas	 = 0;
		}

		// samedi
		$planningSemaine->samedi = $semaine->samedi;
		$samedi			 = new RHDateTime($semaine->samedi);
		if ($samedi->isGT($now)) {
		    // On utilise les disponibilité
		    $planningSemaine->samedi_code	 = $dispo->samedi;
		    $planningSemaine->samedi_entree	 = $dispo->samedi_entree;
		    $planningSemaine->samedi_sortie	 = $dispo->samedi_sortie;
		    $planningSemaine->samedi_pause	 = 0;
		    $planningSemaine->samedi_repas	 = 0;
		}
		else {
		    $planningSemaine->samedi_code	 = 3;
		    $planningSemaine->samedi_entree	 = '00:00';
		    $planningSemaine->samedi_sortie	 = '00:00';
		    $planningSemaine->samedi_pause	 = 0;
		    $planningSemaine->samedi_repas	 = 0;
		}

		// dimanche
		$planningSemaine->dimanche	 = $semaine->dimanche;
		$dimanche			 = new RHDateTime($semaine->dimanche);
		if ($dimanche->isGT($now) || $dimanche->isEqual($now)) {
		    // On utilise les disponibilité
		    $planningSemaine->dimanche_code		 = $dispo->dimanche;
		    $planningSemaine->dimanche_entree	 = $dispo->dimanche_entree;
		    $planningSemaine->dimanche_sortie	 = $dispo->dimanche_sortie;
		    $planningSemaine->dimanche_pause	 = 0;
		    $planningSemaine->dimanche_repas	 = 0;
		}
		else {
		    $planningSemaine->dimanche_code		 = 3;
		    $planningSemaine->dimanche_entree	 = '00:00';
		    $planningSemaine->dimanche_sortie	 = '00:00';
		    $planningSemaine->dimanche_pause	 = 0;
		    $planningSemaine->dimanche_repas	 = 0;
		}

		// Calcul Heures
		$rules = new \RHX\Model\Object\XRules($this->adapter);

		$retard = 0;

		$total = new RHDateTime();
		$total->setTime();

		// Calcul Heure Travaillé
		$diff	 = RHDateTime::diffHours($planningSemaine->lundi_entree, $planningSemaine->lundi_sortie);
		$code	 = (int) $planningSemaine->lundi_code;
		if ($rules->isCountable($code))
		    $total->addHours($diff, false);
		if ($rules->isLate($code))
		    $retard++;
		$diff	 = RHDateTime::diffHours($planningSemaine->mardi_entree, $planningSemaine->mardi_sortie);
		$code	 = (int) $planningSemaine->mardi_code;
		if ($rules->isCountable($code))
		    $total->addHours($diff, false);
		if ($rules->isLate($code))
		    $retard++;
		$diff	 = RHDateTime::diffHours($planningSemaine->mercredi_entree, $planningSemaine->mercredi_sortie);
		$code	 = (int) $planningSemaine->mercredi_code;
		if ($rules->isCountable($code))
		    $total->addHours($diff, false);
		if ($rules->isLate($code))
		    $retard++;
		$diff	 = RHDateTime::diffHours($planningSemaine->jeudi_entree, $planningSemaine->jeudi_sortie);
		$code	 = (int) $planningSemaine->jeudi_code;
		if ($rules->isCountable($code))
		    $total->addHours($diff, false);
		if ($rules->isLate($code))
		    $retard++;
		$diff	 = RHDateTime::diffHours($planningSemaine->vendredi_entree, $planningSemaine->vendredi_sortie);
		$code	 = (int) $planningSemaine->vendredi_code;
		if ($rules->isCountable($code))
		    $total->addHours($diff, false);
		if ($rules->isLate($code))
		    $retard++;
		$diff	 = RHDateTime::diffHours($planningSemaine->samedi_entree, $planningSemaine->samedi_sortie);
		$code	 = (int) $planningSemaine->samedi_code;
		if ($rules->isCountable($code))
		    $total->addHours($diff, false);
		if ($rules->isLate($code))
		    $retard++;
		$diff	 = RHDateTime::diffHours($planningSemaine->dimanche_entree, $planningSemaine->dimanche_sortie);
		$code	 = (int) $planningSemaine->dimanche_code;
		if ($rules->isCountable($code))
		    $total->addHours($diff, false);
		if ($rules->isLate($code))
		    $retard++;

		$planningSemaine->retard = $retard;

		$planningSemaine->heure_travaille = $total->totalHours();

		// Employé
//		$employe		 = $planningSemaine->getEmploye();
		// Avenant de l'employé
		$avenant		 = $employe->getAvenant();
		$hebdo_heure		 = (int) $avenant->hebdo;
		$hebdo_minute		 = 0;
		// Calcul des heures non planiffié
		$diff_heure		 = 0;
		$diff_minute		 = 0;
		$travaille		 = explode(':', $planningSemaine->heure_travaille);
		$travaille_heure	 = (int) $travaille[0];
		$travaille_minute	 = (int) $travaille[1];
		if ($travaille_minute >= $hebdo_minute) {
		    // Calcul normal
		    $diff_minute	 = $travaille_minute - $hebdo_minute;
		    $diff_heure	 = $travaille_heure - $hebdo_heure;
		}
		else {
		    // on enlève une heure
		    $travaille_heure--;
		    $travaille_minute += 60;
		    $diff_minute	 = $travaille_minute - $hebdo_minute;
		    $diff_heure	 = $travaille_heure - $travaille_heure;
		}
		$diff					 = "$diff_heure:$diff_minute";
		$planningSemaine->heure_non_planifie	 = $diff;

		// Sauvegarde
		$idArray[] = $this->save($planningSemaine);
	    }
	}
    }

    /**
     * Nombre d'occurence d'un code activité pour une période données
     * 
     * @param int $codeId
     * @param int $matricule
     * @param int $periodeId
     * @return int
     */
    public function getOccurencePeriode($codeId, $matricule, $periodeId) {
	$count			 = 0;
	// Table Période
	$periodeTable		 = new PeriodeTable($this->adapter);
	$periode		 = $periodeTable->get($periodeId);
	// Semaines dans la période
	$periodeSemaineTable	 = new PeriodeSemaineTable($this->adapter);
	$semaines		 = $periodeSemaineTable->getSemainesByPeriode($periodeId);
	foreach ($semaines as $sem) {
	    $planning = $this->getPlanningByDay($sem->lundi, $matricule);
	    if (!$planning)
		continue;

	    // Parcours des 7 jours de la semaine
	    // lundi
	    if ((int) $planning->lundi_code == (int) $codeId) {
		$count++;
	    }

	    // mardi
	    if ((int) $planning->mardi_code == (int) $codeId) {
		$count++;
	    }

	    // mercredi
	    if ((int) $planning->mercredi_code == (int) $codeId) {
		$count++;
	    }

	    // jeudi
	    if ((int) $planning->jeudi_code == (int) $codeId) {
		$count++;
	    }

	    // vendredi
	    if ((int) $planning->vendredi_code == (int) $codeId) {
		$count++;
	    }

	    // samedi
	    if ((int) $planning->samedi_code == (int) $codeId) {
		$count++;
	    }

	    // dimanche
	    if ((int) $planning->dimanche_code == (int) $codeId) {
		$count++;
	    }
	}

	return $count;
    }

    /**
     * Récupérer les Heures non planifiées sur une période
     * 
     * @param \RHX\Model\Object\Periode $periode
     * @param type $matricule
     * @return float
     */
    public function getHeureNonPlanifie(Periode $periode, $matricule) {
	// requete brute
	$sql			 = 'SELECT SUM(heure_non_plannifie) as somme FROM rh_planning_semaine WHERE lundi BETWEEN "' . $periode->debut . '" AND "' . $periode->fin . '" AND matricule = ' . $matricule;
//	echo $sql . '<br>';
//	var_dump($sql);
	$rows			 = $this->adapter
		->query($sql)
		->execute();
	$heureNonPlanifie	 = 0.0;
	foreach ($rows as $row) {
	    $heureNonPlanifie = floatval($row['somme']);
	}

	return $heureNonPlanifie;
    }

    /**
     * Récupérer les plannings d'un employé pour une période données
     * 
     * @param \RHX\Model\Object\Periode $periode
     * @param int $matricule
     * @return type
     */
    public function getPlanningByPeriode(Periode $periode, $matricule) {
	$rows = $this->select(function(Select $select) use($periode, $matricule) {
		    $where = new Where();
		    $where->between('lundi', $periode->debut, $periode->fin);
		    $where->equalTo('matricule', $matricule);
		    $select->where($where);
		});

	return $rows;
    }

    /**
     * Récupérer le planning semaine correspondant à une semaine
     * 
     * @param \RHX\Model\Object\Semaine $semaine
     * @param int $matricule
     * @return PlanningSemaine
     */
    public function getPlanningBySemmaine(Semaine $semaine, $matricule) {
	$rows = $this->select(function(Select $select) use($semaine, $matricule) {
		    $where = new Where();
		    $where->between('lundi', $semaine->lundi, $semaine->dimanche);
		    $where->equalTo('matricule', $matricule);
		    $select->where($where);
		});

	return $rows->current();
    }

    /**
     * Récupérer les plannings supérieur à la date en cours
     * 
     * @param string $date
     * @param int $site
     * @return ResultSet
     */
    public function getPlanningsByDate($date, $site) {
	$dayName = RHDateTime::dayName($date);
	$lundi = new RHDateTime($date);
	if($dayName != 'lundi'){
	    $lundi->modify('previous monday');
	}
	$dimanche = new RHDateTime($date);
	if(RHDateTime::dayName($date) != 'dimache'){
	    $dimanche->modify('next sunday');
	}
	$adapter = $this->adapter;
	$rows = $this->select(function(Select $select)use($lundi, $dimanche, $site, $adapter) {
		    $where		 = new Where();
		    //$where->greaterThanOrEqualTo('lundi', $date);
		    $where->between('lundi', $lundi->date(), $dimanche->date());
		    // Liste des employes du site
		    $tableEmploye	 = new EmployeTable($adapter);
		    $employeList	 = $tableEmploye->getEmployesBySite($site);
		    $employes	 = array();
		    foreach ($employeList as $e) {
			$employes[] = $e->matricule;
		    }
		    $where->in('matricule', $employes);
		    $select->where($where);
		    //echo '<pre>' .@$select->getSqlString().'</pre>';
		});

	return $rows;
    }

    /**
     * Liste des employés ayant un planning semaine
     *
     * @param int $site
     * @param string $debut
     * @param string $fin
     * @return array
     */
    public function getEmployeHavingPlanning($site, $debut, $fin) {
//	\Zend\Debug\Debug::dump($site, 'Site en paramètre');
//	\Zend\Debug\Debug::dump($debut, 'Debut en paramètre');
//	\Zend\Debug\Debug::dump($fin, 'Fin en paramètre');
	// Liste des employes dans le site
	$tableEmploye	 = new EmployeTable($this->adapter);
	$employeList	 = $tableEmploye->getEmployesBySiteEx2($site, 'poste_rang asc, prenom asc');
//	\Zend\Debug\Debug::dump($employeList->count(), 'nombre employés');
	$employes	 = array();
	// parcours de la liste des employés
	foreach ($employeList as $e) {
	    $plannings = $this->getPlanningsByDateRange($e->matricule, $debut, $fin);
	    if ($plannings->current()) {
		$employes[] = $e;
	    }
	}
	$count = count($employes);
	//echo "<pre>Il y a $count employe(s) ayant un planning";

	return $employes;
    }

    /**
     * Planning Semaine d'un employé sur une période données
     * 
     * @param int $matricule
     * @param string $debut
     * @param string $fin
     * @return ResultSet
     */
    public function getPlanningsByDateRange($matricule, $debut, $fin) {
	$rows = $this->select(function(Select $select)use($matricule, $debut, $fin) {
		    $where = new Where();
			    $where->equalTo('matricule', $matricule);
			    $where->between('lundi', $debut, $fin);
			    //$select->group('matricule');
			    $select->order('lundi ASC');
			    $select->where($where);
			});
	//echo "<pre>{$rows->count()}</pre>";

	return $rows;
    }
    
    /**
     * Nombre de personne à une heure précise
     * 
     * @param string $date
     * @param string $heure
     * @param int $heure
     * @param string $prefix
     * @return array
     */
    public function countPersonne($date, $heure, $site, $prefix = 'lundi'){
	$entree = $prefix .'_entree';
	$sortie = $prefix .'_sortie';
	$code = $prefix .'_code';
	$sql = "SELECT COUNT(p.matricule) AS nb FROM rh_planning_semaine p, rh_site s, rh_employe e WHERE $prefix = '$date' AND ('$heure' BETWEEN p.$entree AND p.$sortie OR p.$entree = '$heure' OR p.$sortie = '$heure') AND $code IN (1, 19, 14, 25, 22, 23, 24) AND e.matricule = p.matricule AND e.site_id = s.id AND s.id = $site";
	$result = $this->getAdapter()->query($sql)->execute();
	$current = $result->current();
	return array(
            'value' => (int)$current['nb'],
            'sql' => $sql,
        );
    }
    
     public function executeQuery($sql) {
	return $this->adapter
			->query($sql)
			->execute();
    }

}

?>
